package eip.chapter3.pubsub.impl;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.axis2.AxisFault;
import org.apache.axis2.client.Options;
import org.apache.axis2.context.ServiceContext;
import org.apache.savan.SavanException;
import org.apache.savan.publication.client.PublicationClient;
import org.apache.savan.storage.SubscriberStore;
import org.apache.savan.util.CommonUtil;

/**
 * This class is the webservice that is called from the client to send
 * the updates. This webservice will send an update to all the registered
 * listeners.
 * 
 * @author nl24167
 */
public class HotelDistributionService {
	
	/** the action to invoke on the registered clients */
	private final String PUB_ACTION = "urn:publish";
	
	/** Axis2's service context, used for sending the updates */
	private ServiceContext serviceContext = null;
	
	/**
	 * Default constructor
	 */
	public HotelDistributionService() {
	}
	
	/**
	 * We implement this 'lifecycle' method to make sure we get a reference
	 * to the serviceContext
	 * 
	 * @param serviceContext
	 * @throws AxisFault
	 */
	public void init(ServiceContext serviceContext) throws AxisFault {
		this.serviceContext = serviceContext;
	}

	/**
	 * The soap method that can be called to send updates to the registered
	 * listeners.
	 * 
	 * @throws SavanException 
	 */
	public void sendUpdates(OMElement input) throws SavanException {
		SOAPFactory factory = OMAbstractFactory.getSOAP11Factory();
		SOAPEnvelope envelope = factory.getDefaultEnvelope();
		envelope.getBody().addChild(input);
		sendToSubscribers(envelope);
	}

	/**
	 * Send a list of updates to the registered listeners 
	 * 
	 * @param updates
	 * @throws SavanException 
	 */
	private void sendToSubscribers(SOAPEnvelope message) throws SavanException  {
		SubscriberStore store = (SubscriberStore) CommonUtil
				.getSubscriberStore(serviceContext.getAxisService());
		Options options = new Options();
		options.setAction(PUB_ACTION);
		PublicationClient.sendPublication(message, serviceContext
				.getConfigurationContext(), options, store);
	}
}
